<template>
  <!-- <div class="layer-container"> -->
  <div
    v-if="visible"
    class="layer-container position-right"
    @click.stop="UpSysPanel()"
  >
    <div class="header">
      <div class="panel-name">图层</div>
      <div class="close-icon" @click="closeLayer">
        <a-icon-font type="iconicon-beifen1" />
      </div>
    </div>

    <div class="layer-body">
      <!-- 实体图层展示，可显隐，关联实体面板中的显隐 -->
      <div class="entity-layer">
        <div class="search-box">
          <a-input
            v-model="entitySearchWords"
            placeholder="搜索实体名称"
            @change="onEntitySearchWordsChange"
          />
        </div>
        <a-collapse
          class="entity-list"
          :bordered="false"
          expand-icon-position="right"
          accordion
          @change="handleCollapseChange"
        >
          <a-collapse-panel
            v-for="item in (entityLayerData)"
            :key="item.entityId"
            style="border: 0; border-radius: 4px; overflow: hidden;"
          >
            <div slot="header">
              <a-icon-font
                v-if="item.hasGISInfo"
                slot="circle"
                type="icontucengdaidilixinxi"
              />
              <a-icon-font v-else slot="circle" type="icontuceng" />
              <span> {{ item.name }} </span>
            </div>
            <div class="entity-second-layer">
              <a-collapse :bordered="false" expand-icon-position="right">
                <a-collapse-panel
                  v-for="(option, i) in item.items"
                  :key="`option-${i}`"
                  style="border: 0; border-radius: 4px; overflow: hidden;"
                >
                  <div
                    slot="header"
                    class="option-header"
                    :class="{ unvisible: !option.visible }"
                  >
                    <div>
                      <a-icon-font slot="attr" type="iconduanlafuhao" />
                      <span> {{ option.name }} </span>
                    </div>

                    <a-icon-font
                      class="eye-icon"
                      :type="
                        option.visible
                          ? 'iconicon-beifen3'
                          : 'icontufenxi-guanbigailan'
                      "
                      @click="itemToggleShow($event, option._id_)"
                    />
                  </div>
                  <div
                    v-for="(attr, attrIndex) in option.children"
                    :key="`attr-${attrIndex}`"
                    class="entity-third-layer"
                  >
                    <div
                      class="option-header"
                      :class="{ unvisible: !attr.visible }"
                    >
                      <div>{{ attr.attrName }}</div>
                      <a-icon-font
                        class="eye-icon"
                        :type="
                          attr.visible
                            ? 'iconicon-beifen3'
                            : 'icontufenxi-guanbigailan'
                        "
                        @click="
                          optionToggleShow($event, option._id_, attr._id_)
                        "
                      />
                    </div>
                  </div>
                </a-collapse-panel>
              </a-collapse>
            </div>
            <!-- <a-icon slot="extra" type="setting"  /> -->
          </a-collapse-panel>
        </a-collapse>
      </div>
      <!-- GIS图层展示， 可拖拽，显隐 -->
      <div class="gis-layer">
        <a-tree
          :tree-data="gisTreeData"
          show-icon
          default-expand-all
          :selectable="false"
          :expanded-keys="expandedKeys"
          draggable
          @drop="onDrop"
        >
          <a-icon slot="switcherIcon" type="down" />
          <a-icon-font slot="gis" type="iconditu2" />
          <a-icon-font slot="circle" type="icondian" />
          <a-icon-font slot="line" type="iconxian" />
          <a-icon-font slot="fill" type="iconmian" />
          <div
            slot="custom"
            slot-scope="item"
            @mouseenter="() => onMouseEnter(item.id)"
            @mouseleave="onMouseLeave"
            @click="clickCategory(item.id)"
          >
            <span>{{ item.title }}</span>
            <!-- <span>{{ item.visible }}</span> -->
            <!-- 是否可见 icon -->
            <span class="trailer-icon">
              <a-icon-font
                v-show="item.id === hoverItemId && !item.disable"
                class="eye-icon"
                :type="
                  item.visible === 1
                    ? 'iconicon-beifen3'
                    : 'icontufenxi-guanbigailan'
                "
                @click="changeGisVisible(item, $event)"
              />
              <a-icon-font
                v-show="!item.disable && item.fixed"
                class="fixed-icon"
                style="color: #1e49f8;"
                type="icona-gudingdaoGISbeifen3"
                @click="changeGisFixed(item, $event)"
              />
            </span>
          </div>
        </a-tree>
      </div>
    </div>
  </div>
  <!-- </div> -->
</template>

<script lang="ts">
/**
 * 搜索地图
 */
import { Component, Watch, Vue, Prop } from 'vue-property-decorator'
import KGraphStore from '@/store/modules/k-graph'
import Draggabilly from 'draggabilly'
import {
  queryPanelInfoByVid,
  updatePanelInfoByPanelId,
} from '@/api/knowledge-graph'
import { debounce, cloneDeep } from 'lodash'

@Component({
  components: {},
})
export default class KGisLayer extends Vue {
  @Prop({ type: Boolean, default: false }) visible!: boolean
  public drag: any = null
  private hoverItemId: number = -1
  public expandedKeys: any = []
  public entityLayerData: any = []
  public allEntityLayerData: any = [] //  所有的实体信息列表

  public get entityLayer() {
    return KGraphStore.entityLayer
  }

  public entitySearchWords: string = '' //  搜索词

  @Watch('entityLayer', { deep: true })
  handleEntityLayer(newValue: any) {
    if (newValue) {
      this.entityLayerData = cloneDeep(newValue)
      this.allEntityLayerData = cloneDeep(newValue)
    }
  }

  public onEntitySearchWordsChange = debounce(() => this._handleSearch(), 200)

  public _handleSearch() {
    this.entityLayerData = this.allEntityLayerData.filter((item: any) => {
      return item.name.includes(this.entitySearchWords)
    })
    if (this.entitySearchWords.length === 0) {
      this.entityLayerData = this.allEntityLayerData
    }
  }
  // 图层树
  public gisData: any[] = [
    {
      id: 55,
      title: 'GIS',
      key: 'gis55',
      slots: {
        icon: 'gis',
      },
      scopedSlots: { title: 'custom' },
      disable: true,
      children: [],
    },
  ]
  @Watch('gisData', { immediate: true, deep: true })
  handleGisData(newValue: any) {
    this.gisTreeData = cloneDeep(newValue)
  }

  public gisTreeData: any = null //  for gis tree data

  /**
   * 图层 GIS
   */
  private get layerList() {
    return KGraphStore.layerList
  }

  @Watch('layerList', { deep: true })
  public layerListChange(newValue: any) {
    if (newValue && newValue.length > 0) {
      this.calcGisLayersTree()
    }
  }

  /**
   * 根据图层数据生成图层树
   * @private
   */
  @Watch('visible')
  public visibleChange(visible: boolean) {
    if (visible) {
      this.calcGisLayersTree()
    }
  }

  /**
   * 根据图层数据生成图层树
   */
  public calcGisLayersTree() {
    const originData = KGraphStore.layerList?.map((layer: any) => {
      return {
        ...layer,
        title: layer.name,
        key: `gis${layer.id}`,
        slots: { icon: layer.type },
        scopedSlots: { title: 'custom' },
      }
    })
    //  根据order 值排序
    this.gisData[0].children = originData.sort((previous: any, next: any) => {
      return previous.order - next.order
    })
  }

  /* 单个ITEM操作 */
  public onMouseEnter(datasetId: number) {
    this.hoverItemId = datasetId
  }

  public onMouseLeave() {
    this.hoverItemId = -1
  }

  /**
   * 拖拽修改图层顺序
   * @param info
   */
  public onDrop(info: any) {
    const key = info.dragNodesKeys[0]
    let position = info.dropPosition
    const index = this.gisData[0].children.findIndex((item: any) => {
      return item.key === key
    })
    const target: any = this.gisData[0].children.find((item: any) => {
      return item.key === key
    })
    if (index > position) {
      position += 1
    } else if (index < position) {
      position -= 1
    } else {
      return
    }
    this.gisData[0].children.splice(index, 1)
    this.gisData[0].children.splice(position, 0, target)
    this.$forceUpdate()
    this.updateLayerOrder(this.gisData[0].children)
  }

  /**
   * 计算图层顺序
   * @param layers
   */
  public updateLayerOrder(layers: any[]) {
    // 顺序修改
    const layerOrder: any = {}
    layers.forEach((layer: any, index1: number) => {
      layerOrder[layer.id] = index1 + 1
    })
    this.$emit('update-layer-order', layerOrder)
  }

  // 点击分类 展开/收起
  public clickCategory(id: number) {
    console.log('id', id)
    const categoryId: string = `gis${id}`
    const index = this.expandedKeys.findIndex((v: any) => v === categoryId)
    if (index < 0) {
      this.expandedKeys.push(categoryId)
    } else {
      this.expandedKeys.splice(index, 1)
    }
  }

  public get projectId() {
    return Number(this.$route.params.id)
  }

  public editingEntityData: any | null = null
  //  获取新的实体信息
  public async queryNewPanelInfo(entityId: number) {
    const response: any = await queryPanelInfoByVid({
      data: {
        projectId: this.projectId,
        vid: entityId,
      },
    })
    if (response.data.code === 100) {
      const { layout } = response.data.result

      this.editingEntityData = response.data.result

      console.log('layout', layout)
      const index = this.entityLayerData.findIndex((item: any) => {
        return item.entityId === entityId
      })
      this.$set(this.entityLayerData[index], 'items', layout.items)
    }
  }
  //  处理collapse 点击
  public async handleCollapseChange(entityId: any) {
    console.log(entityId, 'okok')

    // save the previous editing entityData first
    if (this.editingEntityData) {
      this.updateEntity()
    }

    if (entityId) {
      this.queryNewPanelInfo(entityId)
    } else {
      this.editingEntityData = null
    }
  }
  //  第一级的显隐
  public itemToggleShow($event: Event, id: string) {
    $event.stopPropagation()
    // eslint-disable-next-line no-restricted-syntax
    for (const item of this.editingEntityData.layout.items) {
      if (item._id_ === id) {
        item.visible = !item.visible
        break
      }
    }
  }
  //  第二级的显隐
  public optionToggleShow($event: Event, itemId: string, optionId: string) {
    $event.stopPropagation()
    // eslint-disable-next-line no-restricted-syntax
    for (const item of this.editingEntityData.layout.items) {
      if (item._id_ === itemId) {
        // eslint-disable-next-line no-restricted-syntax
        for (const option of item.children) {
          if (option._id_ === optionId) {
            option.visible = !option.visible
            break
          }
        }
      }
    }
  }

  /**
   * 切换图层显隐
   * @param item
   * @param $event
   */
  public changeGisVisible(item: any, $event: Event) {
    item.dataRef.visible = item.visible === 1 ? 0 : 1
    // this.findTarget(item.id)
    // eslint-disable-next-line no-restricted-syntax
    for (const lastItem of this.gisData[0].children) {
      if (lastItem.id === item.id) {
        lastItem.visible = item.visible === 1 ? 0 : 1
        break
      }
    }
    this.$emit('toggle-layer-visible', item.dataRef)
    $event.stopPropagation()
  }

  /**
   * 修改常驻图层
   * @param item
   * @param $event
   */
  public changeGisFixed(item: any, $event: Event) {
    const { id } = item.dataRef
    this.$emit('cancel-layer-fixed', id)
    $event.stopPropagation()
  }

  public setVisible(item: any, visible: boolean): any {
    // eslint-disable-next-line no-restricted-syntax
    for (const target of item) {
      target.visible = visible
      if (target.children) {
        target.children = this.setVisible(target.children, visible)
      }
    }
    return item
  }

  @Watch('visible', { immediate: true })
  private watchVisible(value: boolean) {
    const that = this
    if (value) {
      setTimeout(() => {
        const $overlay = document.querySelector(
          '.gis-map-component'
        ) as HTMLDivElement
        const $element = document.querySelector(
          '.layer-container'
        ) as HTMLDivElement
        that.drag = new Draggabilly($element, {
          containment: $overlay,
          handle: '.header',
          grid: [1, 1],
        })

        that.drag.on('dragEnd', () => {
          if (!$element.classList.contains('resize-tag')) {
            $element.classList.add('resize-tag')
            $element.style.height = '480px'
          }
        })
      }, 500)
    }
  }

  public async closeLayer() {
    this.entitySearchWords = ''
    if (this.editingEntityData) {
      this.updateEntity()
    }
    KGraphStore.setCurrentToolBarAction(null)

    const response: any = await KGraphStore.updateDashboard()
    if (response.status === 200 && response.data.code === 100) {
      this.$message.success('保存成功')
    } else {
      this.$message.error(response.message)
    }
  }

  public async updateEntity() {
    const updateResponse = await updatePanelInfoByPanelId({
      data: {
        ...this.editingEntityData,
      },
    })
    return updateResponse
  }

  private destroyed() {
    if (this.drag) {
      this.drag.destroy()
    }
  }

  public UpSysPanel() {
    //  set focus box
    KGraphStore.setFocusBoxg('sys')
  }
}
</script>

<style scoped lang="less">
.position-right {
  right: 0;
}

.resize-tag {
  overflow: hidden;
  resize: both;
}

.layer-container {
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.18);
  height: 100%;
  position: absolute;
  top: 1px;
  width: 300px;
  z-index: 800;

  .header {
    align-items: center;
    cursor: grab;
    display: flex;
    justify-content: space-between;
    margin: 9px 12px;

    .close-icon {
      align-items: center;
      border-radius: 2px;
      color: rgb(93, 99, 126);
      cursor: pointer;
      display: flex;
      font-size: 16px;
      padding: 4px;
      position: relative;
      user-select: none;
    }
  }

  .layer-body {
    background: #f9f9fc;
    height: calc(100% - 50px);
    overflow-y: scroll;
    padding: 8px 12px;
    width: 100%;

    .entity-layer {
      height: 80%;

      .search-box {
        box-sizing: border-box;
        padding: 10px;
        width: 100%;

        /deep/ .ant-input {
          border-radius: 16px;
        }
      }

      .entity-list {
        height: 80%;
        overflow-y: scroll;
      }

      .option-header {
        align-items: center;
        display: flex;
        justify-content: space-between;

        .eye-icon {
          cursor: pointer;
          display: none;
        }

        &:hover {
          .eye-icon {
            display: inline-block;
          }
        }
      }

      .unvisible {
        color: #373b52;
        opacity: 0.5;
      }
    }
  }

  /deep/ .ant-collapse-content-box {
    padding: 0;
  }

  /deep/
    .ant-collapse-icon-position-right
    > .ant-collapse-item
    > .ant-collapse-header
    .ant-collapse-arrow {
    right: 0;
    top: 24px;
  }

  /deep/
    .ant-collapse-icon-position-right
    > .ant-collapse-item
    > .ant-collapse-header {
    padding: 12px 16px 0;
  }

  .entity-second-layer {
    padding-left: 16px;
  }

  .entity-third-layer {
    padding-left: 32px;
  }

  /deep/ .ant-tree-treenode-switcher-open {
    position: relative;
  }

  /deep/ .ant-tree li .ant-tree-switcher {
    position: absolute;
    right: 5px;
  }

  /deep/ .ant-tree li .ant-tree-node-content-wrapper {
    align-items: center;
    display: flex;
    width: 100%;
  }

  /deep/ .ant-tree-title {
    display: inline-block;
    position: relative;
    width: 100%;
  }

  /deep/ .trailer-icon {
    position: absolute;
    right: 6px;

    .eye-icon {
      cursor: pointer;
    }

    .fixed-icon {
      cursor: pointer;
      margin-left: 6px;
    }
  }
}
</style>
